#include "stdafx.h"
#include "EnumList.h"
#include "RealIEnumVARIANT.h"

RealIEnumVARIANT::RealIEnumVARIANT(EnumList *pList) : m_count(1), m_list(pList), m_pCurItem(NULL)
{
    if (m_list)
    {
        m_list->AddRef();
        m_pCurItem = m_list->head;
    }
}

RealIEnumVARIANT::~RealIEnumVARIANT()
{
    if (m_list) m_list->Release();
}

HRESULT STDMETHODCALLTYPE RealIEnumVARIANT::QueryInterface(REFIID riid, void **ppv)
{
    if (IsEqualIID(riid, IID_IUnknown) ||
        IsEqualIID(riid, IID_IEnumVARIANT))
    {
        *ppv = this;
        AddRef();
        return S_OK;
    }

    *ppv = NULL;
    return E_NOINTERFACE;
}

ULONG STDMETHODCALLTYPE RealIEnumVARIANT::AddRef()
{
    return ++m_count;
}

ULONG STDMETHODCALLTYPE RealIEnumVARIANT::Release()
{
    if (--m_count == 0)
    {
        delete this;
        InterlockedDecrement(&OutstandingObjects);
        return 0;
    }
    return m_count;
}

HRESULT STDMETHODCALLTYPE RealIEnumVARIANT::Next(ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
{
    if (m_pCurItem == NULL) return S_FALSE;
    ULONG i;
    for (i = 0; i < celt && m_pCurItem; ++i, m_pCurItem = m_pCurItem->next)
    {
        VariantCopy(&rgVar[i], &m_pCurItem->data);
    }
    if (pCeltFetched != NULL) *pCeltFetched = i;
    for (; i < celt; ++i) rgVar[i].vt = VT_EMPTY;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE RealIEnumVARIANT::Skip(ULONG celt)
{
    while (celt-- && m_pCurItem)
        m_pCurItem = m_pCurItem->next;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE RealIEnumVARIANT::Reset()
{
    if (m_list == NULL) return S_FALSE;
    m_pCurItem = m_list->head;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE RealIEnumVARIANT::Clone(IEnumVARIANT **ppEnum)
{
    RealIEnumVARIANT *p = new RealIEnumVARIANT(m_list);
    if (p == NULL)
    {
        *ppEnum = NULL;
        return E_OUTOFMEMORY;
    }
    p->m_pCurItem = m_pCurItem;
    *ppEnum = p;
    InterlockedIncrement(&OutstandingObjects);
    return S_OK;
}
